import * as d3 from 'd3'
export function drawchart(vue) {
  var _chart = {}
  _chart.vue = vue

  var numberOfAxis = 11
  var useKeys = ['风向', 'AQI', 'CO(毫克每立方米)', 'NO2(微克每立方米)', 'O3(微克每立方米)', 'PM10(微克每立方米)', 'PM2.5(微克每立方米)',
    'PSFC(Pa)', 'RH(%)', 'SO2(微克每立方米)', '摄氏温度', '风速']
  var _colors = function(i) {
    // let mycolor = ['#949483', '#f47b7b', '#9f1f5c', '#ef9020', '#00af3e',
    //   '#85b7e2', '#29245c', '#ffd616', '#e5352b', '#e990ab', '#0081b4',
    //   '#96cbb3', '#91be3e', '#39a6dd']
    let newColor = ['#8db5d3', '#f7c3b0', '#a1ede9', '#ffa05a', '#c492fd', '#3baeff',
      '#aed8ff', '#69bcaf', '#f2e280', '#d4cff7', '#fa8170', '#8f89ff', '#93d47f', '#ffc34e']
    return newColor[i % 14]
  }
  var _svg,
    _upsvg, _upaxisG, _uppotG,
    _subsvg, _sublineG, _subaxisG, _subdefs, _subSGup, _subSGsub

  var arrowData = [{
    path: 'M 0,0 m -5,-5 L 5,0 L -5,5 Z',
    viewbox: '-5 -5 10 10'
  }]

  function initLayout(divHeight, divWidth, data) {
    let _layout = {}
    _layout._height = divHeight
    _layout._width = divWidth
    _layout.numberOfLines = 361
    _layout.numberOfAxis = 11
    _layout._subGheight = divHeight * 0.5
    _layout.upGheight = divHeight * 0.4 - 20
    _layout._pandings = {
      top: 5,
      left: 50,
      right: 15,
      bottom: 10
    }
    _layout.color = function(i) {
      // let mycolor = ['#949483', '#f47b7b', '#9f1f5c', '#ef9020', '#00af3e',
      //   '#85b7e2', '#29245c', '#ffd616', '#e5352b', '#e990ab', '#0081b4',
      //   '#96cbb3', '#91be3e', '#39a6dd']
      let newColor = ['#8db5d3', '#f7c3b0', '#a1ede9', '#ffa05a', '#c492fd', '#3baeff',
        '#aed8ff', '#69bcaf', '#f2e280', '#d4cff7', '#fa8170', '#8f89ff', '#93d47f', '#ffc34e']
      return newColor[i % 14]
    }
    _layout.axisColor = function(axis) {
      let color = ['#Ob44co', '', '#3e3123', '#654047', '#c1888c', '#997c61', '#deb89e', '#98dcf3',
        '#fce37e', '#7b6b57', '#fb570b', '#0260eb']
      return color[useKeys.indexOf(axis)]
    }
    _layout.aqiColor = ['#84c45e', '#f9d92a', '#fda300', '#ff3406', '#cf0032', '#49224f']
    let axisPadding = divWidth / _layout.numberOfAxis
    let keys = useKeys
    _layout._y = {}
    _layout._yUpY = {}
    _layout._yUpX = {}
    _layout._x = d3.scaleBand()
      .domain(keys)
      .range([_layout._pandings.left, _layout._pandings.left + (numberOfAxis) * axisPadding -
          _layout._pandings.right])

    _layout.subAxisData = []

    _layout._keys = keys.filter(function(d) {
      let extent = d3.extent(data, function(p) {
        return +p[d]
      })

      // 平行坐标的比例尺
      if (d !== '风向') {
        _layout.subAxisData.push([{'x': d, 'y': extent[0]}, {'x': d, 'y': extent[1]}])
        _layout._y[d] = d3.scaleLinear()
          .domain(extent)
          .range([_layout._height - _layout._pandings.bottom, _layout._height - _layout._subGheight])
      }

      // 散点图的y坐标
      _layout._yUpY[d] = d3.scaleLinear()
        .domain(extent)
        .range([_layout.upGheight, _layout._pandings.top])

      // 散点图的x坐标
      _layout._yUpX[d] = d3.scaleLinear()
        .domain(extent)
        .range([0, _layout._x.bandwidth()])

      return d !== '风向'
    })
    _layout.upAxisData = []
    useKeys.forEach(function(_, i) {
      if (i < useKeys.length - 1) {
        _layout.upAxisData.push({'y': useKeys[i], 'x': useKeys[i + 1]})
      }
    })
    _layout.centroX = _layout._x('风向')
    _layout.centroYUp = _layout._height - _layout._pandings.bottom - _layout._subGheight * 0.25
    _layout.centroYSub = _layout._height - _layout._pandings.bottom - _layout._subGheight * 0.75
    _layout._r = (_layout._subGheight) / 4
    _layout.windScale = function(angle) {
      let rad = angle * Math.PI / 180
      if (angle > 180) {
        return [_layout.centroX + Math.sin(rad) * _layout._r, _layout.centroYSub + Math.cos(rad) * _layout._r]
      } else {
        return [_layout.centroX + Math.sin(rad) * _layout._r, _layout.centroYUp + Math.cos(rad) * _layout._r]
      }
    }
    _layout._colors = function(i) {
      let mycolor = ['#949483', '#f47b7b', '#9f1f5c', '#ef9020', '#00af3e',
        '#85b7e2', '#29245c', '#ffd616', '#e5352b', '#e990ab', '#0081b4',
        '#96cbb3', '#91be3e', '#39a6dd'
      ]
      return mycolor[i % 14]
    }
    return _layout
  }

  _chart.render = function(divId, data) {
    let divHeight = document.getElementById(divId).offsetHeight
    let divWidth = document.getElementById(divId).offsetWidth
    if (!_svg) {
      _svg = d3.select('#' + divId)
        .append('svg')
        .attr('class', 'parallelScatter')
        .attr('height', divHeight)
        .attr('width', divWidth)
    }
    let layout = initLayout(divHeight, divWidth, data)
    renderupG(_svg, layout, data)
    rendersubG(_svg, layout, data)
  }

  function rendersubG(svg, layout, data) {
    if (!_subsvg) {
      _subsvg = svg.append('g')
        .attr('class', 'parallel')
        .attr('transform', 'translate(' + 0 + ',' + 0 + ')')
    }
    renderLines(_subsvg, layout, data)
    renderParaAxis(_subsvg, layout)
  }

  function renderLines(subsvg, layout, data) {
    if (!_sublineG) {
      _sublineG = subsvg.append('g')
        .attr('class', 'pLines')
    }
    let _line = d3.line()
    let gLines = _sublineG.selectAll('path.line')
      .data(data, d => d.city_name)

    gLines.transition()
      .duration(750)
      .attr('d', function(d, i) {
        let line = []
        line.push(layout.windScale(d['风向']))
        useKeys.filter(o => o !== '风向').forEach(o => {
          line.push([layout._x(o), layout._y[o](d[o])])
        })
        return _line(line)
      })
      .style('stroke', d => layout.color(d.category))

    gLines.enter()
      .append('path')
      .style('stroke', d => layout.color(d.category))
      .style('fill', 'none')
      .style('opacity', 0.6)
      .attr('class', 'line')
      .attr('d', function(d) {
        let line = []
        line.push(layout.windScale(d['风向']))
        useKeys.filter(o => o !== '风向').forEach(o => {
          line.push([layout._x(o), layout._y[o](d[o])])
        })
        return _line(line)
      })
  }

  function renderParaAxis(subsvg, layout) {
    if (!_subdefs) {
      _subdefs = subsvg.append('svg:defs')
        .selectAll('marker')
        .data(arrowData)
        .enter()
        .append('svg:marker')
        .attr('id', 'marker_arrow')
        .attr('markerHeight', 5)
        .attr('markerWidth', 5)
        .attr('markerUnits', 'strokeWidth')
        .attr('orient', 'auto')
        .attr('refX', 0)
        .attr('refY', 0)
        .attr('viewBox', function(d) {
          return d.viewbox
        })
        .append('svg:path')
        .attr('d', function(d) {
          return d.path
        })
    }
    let _line = d3.line()

    if (!_subaxisG) {
      _subaxisG = subsvg.append('g')
        .attr('class', 'pAxis')
    }

    let gAxis = _subaxisG.selectAll('.paxis')
      .data(layout.subAxisData, d => d[0].x)

    gAxis.selectAll('.brush')
      .each(function(d) {
        let centro = layout._x(d[0].x)
        let height = layout._height - layout._subGheight
        d3.select(this).call(layout._y[d[0].x].brush = d3.brushY().extent([
          [centro - 5, height],
          [centro + 5, layout._height]
        ])
          .on('end', function() {
            brushed(layout._y)
          }))
      })

    // gAxis.selectAll('path.line')
    //   .transition()
    //   .duration(750)
    //   .attr('d', function(d) {
    //     let line = d.map(function(o) {
    //       return [layout._x(o.x), layout._y[o.x](o.y)]
    //     })
    //     return _line(line)
    //   })

    let enterNode = gAxis.enter()
      .append('g')
      .attr('class', 'paxis')

    enterNode.append('path')
      .style('stroke', 'black')
      .attr('class', 'line')
      .attr('d', function(d) {
        let line = d.map(function(o) {
          return [layout._x(o.x), layout._y[o.x](o.y)]
        })
        return _line(line)
      })
      .attr('marker-end', 'url(#marker_arrow)')

    enterNode.append('text')
      .attr('transform', function(d) {
        let line = d.map(function(o) {
          return [layout._x(o.x), layout._y[o.x](o.y)]
        })
        return 'translate(' + (line[1][0] - 5 * d[0].x.split('(')[0].length) + ',' + (line[1][1] - 10) + ')'
      })
      .text(function(d) {
        return d[0].x.split('(')[0]
      })

    enterNode.append('circle')
      // .filter(function(d) {
      //   return d[0].x !== 'AQI'
      // })
      .attr('cx', function(d) {
        let line = d.map(function(o) {
          return [layout._x(o.x), layout._y[o.x](o.y)]
        })
        return line[1][0]
      })
      .attr('cy', function(d) {
        let line = d.map(function(o) {
          return [layout._x(o.x), layout._y[o.x](o.y)]
        })
        return (line[1][1] - 30)
      })
      .attr('r', 5)
      .style('fill', d => {
        return layout.axisColor(d[0].x)
      })

    enterNode.append('g')
      .attr('class', 'brush')
      .each(function(d) {
        let centro = layout._x(d[0].x)
        let height = layout._height - layout._subGheight
        d3.select(this).call(layout._y[d[0].x].brush = d3.brushY().extent([
          [centro - 5, height],
          [centro + 5, layout._height]
        ])
          .on('end', function() {
            brushed(layout._y)
          }))
      })

    if (_subaxisG.select('.windAxis').empty()) {
      let gWindAxis = _subaxisG.append('g')
        .attr('class', 'windAxis')

      gWindAxis.append('text')
        .attr('transform', 'translate(' + (layout._x('风向') - 10) + ',' + (layout._height - layout._subGheight - 10) + ')')
        .text('风向')
      gWindAxis.append('circle')
        .attr('transform', 'translate(' + layout._x('风向') + ',' + (layout._height - layout._subGheight - 30) + ')')
        .attr('r', 5)
        .style('fill', function() {
          return layout.axisColor('风向')
        })
      renderSG(gWindAxis, layout)
    }
  }

  function renderSG(subsvg, layout) {
    let thisSId = '风向'
    renderSGsub(subsvg, thisSId, layout)
    renderSGup(subsvg, thisSId, layout)
  }

  function renderSGup(subsvg, thisSId, layout) {
    var data = [{
      startAngle: 0,
      endAngle: Math.PI
    }]
    let radius = layout._r
    var arc = d3.arc().outerRadius(radius).innerRadius(radius - 1)

    if (!_subSGup) {
      _subSGup = subsvg.append('g')
    }
    _subSGup
      .selectAll('path.arc')
      .data(data)
      .enter()
      .append('path')
      .attr('class', 'arc')
      .style('stroke', 'black')

    _subSGup
      .selectAll('path.arc')
      .attr('transform', 'translate(' + layout._x(thisSId) + ',' + layout.centroYUp + ')')
      .attr('d', function(d, i) {
        return arc(d, i)
      })
  }

  function renderSGsub(subsvg, thisSId, layout) {
    var data = [{
      startAngle: 2 * Math.PI,
      endAngle: Math.PI
    }]
    let radius = layout._r
    var arc = d3.arc().outerRadius(radius).innerRadius(radius - 1)
    if (!_subSGsub) {
      _subSGsub = subsvg.append('g')
    }
    _subSGsub
      .selectAll('path.arc')
      .data(data)
      .enter()
      .append('path')
      .attr('class', 'arc')
      .style('stroke', 'black')

    _subSGsub.selectAll('path.arc')
      // .transition()
      // .duration(500)
      .attr('transform', 'translate(' + layout._x(thisSId) + ',' + layout.centroYSub + ')')
      .attr('d', function(d, i) {
        return arc(d, i)
      })
  }

  // 绘制散点图
  function renderupG(svg, layout, data) {
    if (!_upsvg) {
      _upsvg = svg.append('g')
        .attr('class', 'scatter')
        .attr('transform', 'translate(' + 0 + ',' + layout._pandings.top + ')')
      layout._uplines = d3.line()
        .x(function(d) {
          return layout._upx(d.x)
        })
        .y(function(d) {
          return layout._upy(d.y)
        })
    }
    renderUpAsix(_upsvg, layout)
    renderPots(_upsvg, layout, data)
  }

  function renderUpAsix(upsvg, layout) {
    let line = d3.line()

    if (!_upaxisG) {
      _upaxisG = upsvg.selectAll('.scatterAxis')
        .data(layout.upAxisData, d => d.x + '-' + d.y)

      _upaxisG.selectAll('.yAxis')
        .transition()
        .duration(750)
        .attr('d', function(d) {
          return line([[layout._x(d.y), layout.upGheight],
            [layout._x(d.y), layout._pandings.top]])
        })

      _upaxisG.selectAll('.xAxis')
        .transition()
        .duration(750)
        .attr('d', function(d) {
          return line([[layout._x(d.y), layout.upGheight],
            [layout._x(d.x), layout.upGheight]])
        })

      let enterNode = _upaxisG.enter()
        .append('g')
        .attr('class', 'scatterAxis')

      enterNode.append('path')
        .attr('class', 'yAxis')
        .attr('d', function(d) {
          return line([[layout._x(d.y), layout.upGheight],
            [layout._x(d.y), layout._pandings.top]])
        })
        .style('stroke', 'black')
        .style('stroke-width', 1)
        .attr('marker-end', 'url(#marker_arrow)')

      enterNode.append('path')
        .attr('class', 'xAxis')
        .attr('d', function(d) {
          return line([[layout._x(d.y), layout.upGheight],
            [layout._x(d.x), layout.upGheight]])
        })
        .style('stroke', 'black')
        .style('stroke-width', 1)
        .attr('marker-end', 'url(#marker_arrow)')
    }
  }

  function renderPots(upsvg, layout, data) {
    if (!_uppotG) {
      _uppotG = upsvg.append('g')
        .attr('class', 'dots')
    }

    layout.upAxisData.forEach(function(scatter, i) {
      let gCircle = _uppotG.selectAll('circle._' + i)
        .data(data, d => d.city_name)

      gCircle.transition()
        .duration(750)
        .attr('cx', function(d) {
          return layout._yUpX[scatter.x](d[scatter.x]) + layout._x(scatter.y)
        })
        .attr('cy', function(d) {
          return layout._yUpY[scatter.y](d[scatter.y])
        })

      gCircle.enter()
        .append('circle')
        .attr('class', 'bubble _' + i)
        // .attr('class', '')
        .style('stroke', d => layout.color(d.category))
        .style('fill', function(_, j) {
          return _colors(j)
        })
        .style('opacity', 0.6)
        .attr('cx', function(d) {
          return layout._yUpX[scatter.x](d[scatter.x]) + layout._x(scatter.y)
        })
        .attr('cy', function(d) {
          return layout._yUpY[scatter.y](d[scatter.y])
        })
        .attr('r', 1)
    })
  }

  function brushed(brushs) {
    let activate = []
    _subaxisG.selectAll('.brush').each(function(d) {
      let dimension = d[0].x
      let extent = d3.brushSelection(this)
      if (extent !== null) {
        activate.push({
          'dimension': dimension,
          'extent': extent
        })
      }
    })
    let selectCity = []
    _sublineG.selectAll('path.line')
      .style('opacity', 0)
      .filter(function(d) {
        let flag = 0
        activate.forEach(function(o) {
          if (brushs[o.dimension](d[o.dimension]) >= o.extent[0] &&
             brushs[o.dimension](d[o.dimension]) <= o.extent[1]) {
            flag += 1
          }
        })
        if (flag === activate.length) {
          selectCity.push(d.city_name)
          return d
        }
      })
      .style('opacity', 1)

    _uppotG.selectAll('.bubble')
      .style('opacity', 0)
      .filter(function(d) {
        if (selectCity.indexOf(d.city_name) !== -1) {
          return d
        }
      })
      .style('opacity', 1)
    _chart.vue.chart.steelChart.selectedCity(selectCity)
    _chart.vue.chart.mapChart.showSelectedCity(selectCity)
  }

  _chart.filterByCluster = function(groups, dimension) {
    _sublineG.selectAll('path.line')
      .style('opacity', 0)
      .filter(function(d) {
        if (groups.indexOf(d[dimension]) !== -1) {
          return d
        }
      })
      .style('opacity', 1)

    _uppotG.selectAll('.bubble')
      .style('opacity', 0)
      .filter(function(d) {
        if (groups.indexOf(d[dimension]) !== -1) {
          return d
        }
      })
      .style('opacity', 1)
  }
  return _chart
}
